package com.uduemc.security.browser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import com.uduemc.security.browser.bean.MyLoginUrlAuthenticationEntryPoint;
import com.uduemc.security.core.authentication.AbstractChannelSecurityConfig;
import com.uduemc.security.core.filter.SmsValidateCodeFilter;
import com.uduemc.security.core.filter.ValidateCodeFilter;

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

	/**
	 * 配置加密、验证密码方法
	 * 需要配置实现 PasswordEncoder 接口类
	 * BCryptPasswordEncoder 是内置的加密方法，推荐使用
	 * @return
	 */
	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	
	// 配置登录成功执行自定义的动作类
	@Autowired
	public AuthenticationSuccessHandler myAuthenticationSuccessHandler;
	
	// 配置登录失败执行自定义的动作类
	@Autowired
	public AuthenticationFailureHandler myAuthenticationFailureHandler;
	
	@Autowired
	public ValidateCodeFilter validateCodeFilter;
	
	@Autowired
	private AbstractChannelSecurityConfig abstractChannelSecurityConfig;
	
	@Autowired
	private SmsValidateCodeFilter smsValidateCodeFilter;
		
	@Override
	protected void configure(HttpSecurity http) throws Exception {
		// 提交表单的url是必须要经过表单验证的
		validateCodeFilter.setLoginProcessingUrl("/authentication/form");
		smsValidateCodeFilter.setLoginProcessingUrl("/authentication/mobile");
		
		// 将过滤器添加至 UsernamePasswordAuthenticationFilter 前面
		http.addFilterBefore(smsValidateCodeFilter, UsernamePasswordAuthenticationFilter.class)
			.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
			.formLogin()	// 通过表单来进行登录校验
				.loginPage("/authentication/require")	// 配置登录页面
				.loginProcessingUrl("/authentication/form")	// 提交登录表单的url
				//.successHandler(myAuthenticationSuccessHandler)	// 自定义登录成功后处理类
				.failureHandler(myAuthenticationFailureHandler) // 自定义登录失败后处理的类
			.and()
				.exceptionHandling()	//添加自定义异常入口，处理accessdeine异常
				.authenticationEntryPoint(new MyLoginUrlAuthenticationEntryPoint("/authentication/require"))
		// http.httpBasic()	// 通过 Basic 进行校验
			.and()
				.authorizeRequests()	// authorizeRequests： 对请求进行授权
				.antMatchers("/uduemc-signIn.html","/authentication/*","/image/code*","/sms/code").permitAll()	// 除了 /uduemc-signIn.html 请求可以访问以外！
				.anyRequest()			// anyRequest：任何请求
				.authenticated()		// 都需要身份认证
			.and()
				.csrf().disable()		// 关闭 csrf 验证
				.apply(abstractChannelSecurityConfig);		// 加入短信验证配置
	}
}
